package com.cavy.platform.client.domain;

import com.cavy.platform.client.BeansProvider;
import com.cavy.platform.client.message.JobDispatcher;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * @author 唐旭
 * @Date 2018/7/20
 * 任务生成后就不可变
 */
@Slf4j
@Data
@Accessors(chain = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "className", defaultImpl = Job.class)
@JsonSubTypes({
        @JsonSubTypes.Type(value = GitRemoteJob.class, name = "GitRemoteJob"),
        @JsonSubTypes.Type(value = Job.class, name = "Job")})
public class Job implements ContainerRunnable {
    protected String number;
    protected String pipelineName;
    protected String projectName;
    protected String workspaceName;
    protected List<Stage> jobStageList = new ArrayList<>();
    protected Date createTime = new Date();
    protected Date runningTimeOut;

    protected Thread thread;
    protected volatile boolean run = true;
    protected Stage currentStage;

    /**
     * 1,启动线程
     * 2,发送消息?是否要发送job已经开始执行的消息呢?
     */
    @Override
    public void run(RunningParameter parameter, int index) {
        parameter.setJobInfo(this);
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Iterator<Stage> iterator = jobStageList.iterator();
                    while (run && iterator.hasNext()) {
                        currentStage = iterator.next();
                        currentStage.run(parameter, index);
                        run = !currentStage.hasError();
                    }
                } catch (ContainerRunningException e) {
                    log.error(e.getMessage());
                } finally {
                    JobDispatcher bean = BeansProvider.getBean(JobDispatcher.class);
                    assert bean != null;
                    bean.removeJob(number, pipelineName, projectName, workspaceName);
                }
            }
        });
        String threadName = getThreadName();
        thread.setName(threadName);
        parameter.setJobThreadName(threadName);
        thread.start();
    }

    private String getThreadName() {
        return "JOB" + RunningParameter.THREAD_NAME_SEPARATOR + workspaceName + RunningParameter.THREAD_NAME_SEPARATOR
                + projectName + RunningParameter.THREAD_NAME_SEPARATOR +
                pipelineName + RunningParameter.THREAD_NAME_SEPARATOR + number;
    }

    @Override
    public void stop() throws InterruptedException, ContainerRunningException {
        run = false;
        currentStage.stop();
    }

    public void join() throws InterruptedException {
        thread.join();
    }
}
